// 
// SoapTrace.Net - A soap message monitoring utility. 
// 
// Copyright (C) 2004 Matthew Ward
// 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
// 
// Matthew Ward (mrward@users.sourceforge.net)
// 

using NUnit.Framework;
using SoapTrace.Core.Formatters;
using SoapTrace.Tests.Utils;
using SoapTrace.Tests.Config;
using System;
using System.Configuration;
using System.IO;

namespace SoapTrace.Tests
{
	/// <summary>
	/// Tests the <see cref="SoapTrace.Core.Formatters.WebServicesDescriptionLanguageFile"/>
	/// handling of a document literal wsdl file.
	/// </summary>
	[ TestFixture ]
	public class DocumentLiteralWsdlFileTestFixture
	{
		/// <summary>
		/// The wsdl file object under test.
		/// </summary>
		private WebServicesDescriptionLanguageFile m_WsdlFile;

		/// <summary>
		/// The web service associated with the wsdl file.
		/// </summary>
		private WebService m_WebService;

		/// <summary>
		/// The web service operations associated with the wsdl file.
		/// </summary>
		private WebServiceOperationCollection m_WebServiceOperations;

		/// <summary>
		/// Expected web service details.
		/// </summary>
		private WebService m_ExpectedWebService;

		/// <summary>
		/// Initialises each test.
		/// </summary>
		[ SetUp ]
		public void Init( )
		{
			// Set up the expected web service.

			m_ExpectedWebService = new WebService( );
			m_ExpectedWebService.Name = "MathsService";
			m_ExpectedWebService.Uri = "/MathWebService/Maths.asmx";

			AddExpectedWebServiceOperations( );

			m_WsdlFile = new WebServicesDescriptionLanguageFile( );

			StringReader Reader = new StringReader( GetWsdl( ) );
			
			m_WsdlFile.Load( Reader );

			m_WebService = m_WsdlFile.WebService;

			m_WebServiceOperations = m_WebService.Operations;
		}

		/// <summary>
		/// Check that the wsdl file reads the correct web service name
		/// </summary>
		[ Test ]
		public void WebServiceName( )
		{
			Assert.AreEqual( m_ExpectedWebService.Name, m_WebService.Name,
				"Web service name is incorrect." );
		}

		/// <summary>
		/// Check the uri extracted from the wsdl file is correct.
		/// </summary>
		[ Test ]
		public void WebServiceUri( )
		{
			Assert.AreEqual( m_ExpectedWebService.Uri, m_WebService.Uri,
				"Web service uri is incorrect." );
		}

		/// <summary>
		/// Checks that the correct number of web services were extracted.
		/// </summary>
		[ Test ]
		public void WebServiceCount( )
		{
			Assert.AreEqual( m_ExpectedWebService.Operations.Count, 
				m_WebServiceOperations.Count, 
				"Web service count is incorrect." );
		}

		/// <summary>
		/// Tests the first web service operation
		/// </summary>
		[ Test ]
		public void WebServiceOperations( )
		{
			for( int i = 0; i < m_WebServiceOperations.Count; ++i )
			{
				WebServiceOperation Operation = m_WebServiceOperations[ i ];

				WebServiceOperation ExpectedOperation = m_ExpectedWebService.Operations[ i ];

				Assert.AreEqual( ExpectedOperation.Name, Operation.Name,
					"Expected operation name is incorrect." );

				Assert.AreEqual( ExpectedOperation.Parameters.Count, 
					Operation.Parameters.Count,
					String.Concat( "Expected number of parameters is wrong. Name=", ExpectedOperation.Name ) );

				WebServiceTestUtility.CompareParameters( ExpectedOperation, Operation );

				WebServiceTestUtility.CompareReturnValue( ExpectedOperation, Operation );
			}
		}

		/// <summary>
		/// Adds expected web service operations to the web service.
		/// </summary>
		private void AddExpectedWebServiceOperations( )
		{
			// Add first operation.

			WebServiceOperation Operation = new WebServiceOperation( );
			Operation.Name = "Add";

			// Add parameters.

			AddExpectedParametersForAddMethod( Operation );

			// Add return values.

			AddExpectedReturnValueForAddMethod( Operation );

			m_ExpectedWebService.Operations.Add( Operation );


			// Add second operation.

			Operation = new WebServiceOperation( );
			Operation.Name = "Test";

			// Add parameters.

			AddExpectedParametersForTestMethod( Operation );

			// Add return values.

			AddExpectedReturnValueForTestMethod( Operation );

			m_ExpectedWebService.Operations.Add( Operation );
		}

		/// <summary>
		/// Adds expected parameters for the Test method's web service operation.
		/// </summary>
		/// <param name="operation">The web service operation.</param>
		private void AddExpectedParametersForTestMethod( WebServiceOperation operation )
		{
			WebServiceParameter Parameter = new WebServiceParameter( );
			Parameter.Name = "xml";
			Parameter.Display = true;
			Parameter.ParameterType = "string";
			operation.Parameters.Add( Parameter );			

			Parameter = new WebServiceParameter( );
			operation.Parameters.Add( Parameter );
			Parameter.Name = "text";
			Parameter.Display = true;
			Parameter.ParameterType = "string";
		}

		/// <summary>
		/// Adds expected parameters for the Add method's web service operation.
		/// </summary>
		/// <param name="operation">The web service operation.</param>
		private void AddExpectedParametersForAddMethod( WebServiceOperation operation )
		{
			WebServiceParameter Parameter = new WebServiceParameter( );
			Parameter.Name = "value1";
			Parameter.Display = true;
			Parameter.ParameterType = "int";
			operation.Parameters.Add( Parameter );			

			Parameter = new WebServiceParameter( );
			operation.Parameters.Add( Parameter );
			Parameter.Name = "value2";
			Parameter.Display = true;
			Parameter.ParameterType = "int";
		}

		/// <summary>
		/// Adds expected return value to the web service operation.
		/// </summary>
		/// <param name="operation">The web service operation.</param>
		private void AddExpectedReturnValueForTestMethod( WebServiceOperation operation )
		{
			WebServiceReturnValue ReturnValue = new WebServiceReturnValue( );
			ReturnValue.Name = "TestResult";
			ReturnValue.Display = true;
			ReturnValue.ParameterType = "string.array";
			
			operation.ReturnValue = ReturnValue;
		}
		
		/// <summary>
		/// Adds expected return value to the web service operation.
		/// </summary>
		/// <param name="operation">The web service operation.</param>
		private void AddExpectedReturnValueForAddMethod( WebServiceOperation operation )
		{
			WebServiceReturnValue ReturnValue = new WebServiceReturnValue( );
			ReturnValue.Name = "AddResult";
			ReturnValue.Display = true;
			ReturnValue.ParameterType = "int";
			
			operation.ReturnValue = ReturnValue;
		}		
		
		/// <summary>
		/// Gets the wsdl used in this text fixture.
		/// </summary>
		/// <returns>A wsdl string.</returns>
		private string GetWsdl( )
		{
			return "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
				"<definitions xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:s=\"http://www.w3.org/2001/XMLSchema\" xmlns:s0=\"http://tempuri.org/\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:tm=\"http://microsoft.com/wsdl/mime/textMatching/\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" targetNamespace=\"http://tempuri.org/\" xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\r\n" +
				"  <types>\r\n" +
				"    <s:schema elementFormDefault=\"qualified\" targetNamespace=\"http://tempuri.org/\">\r\n" +
				"      <s:element name=\"Add\">\r\n" +
				"        <s:complexType>\r\n" +
				"          <s:sequence>\r\n" +
				"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"value1\" type=\"s:int\" />\r\n" +
				"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"value2\" type=\"s:int\" />\r\n" +
				"          </s:sequence>\r\n" +
				"\r\n" +
				"        </s:complexType>\r\n" +
				"      </s:element>\r\n" +
				"      <s:element name=\"AddResponse\">\r\n" +
				"        <s:complexType>\r\n" +
				"          <s:sequence>\r\n" +
				"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"AddResult\" type=\"s:int\" />\r\n" +
				"          </s:sequence>\r\n" +
				"        </s:complexType>\r\n" +
				"      </s:element>\r\n" +
				"\r\n" +
				"      <s:element name=\"Test\">\r\n" +
				"        <s:complexType>\r\n" +
				"          <s:sequence>\r\n" +
				"            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"xml\" type=\"s:string\" />\r\n" +
				"            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"text\" type=\"s:string\" />\r\n" +
				"          </s:sequence>\r\n" +
				"        </s:complexType>\r\n" +
				"      </s:element>\r\n" +
				"      <s:element name=\"TestResponse\">\r\n" +
				"\r\n" +
				"        <s:complexType>\r\n" +
				"          <s:sequence>\r\n" +
				"            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"TestResult\" type=\"s0:ArrayOfString\" />\r\n" +
				"          </s:sequence>\r\n" +
				"        </s:complexType>\r\n" +
				"      </s:element>\r\n" +
				"      <s:complexType name=\"ArrayOfString\">\r\n" +
				"        <s:sequence>\r\n" +
				"          <s:element minOccurs=\"0\" maxOccurs=\"unbounded\" name=\"string\" nillable=\"true\" type=\"s:string\" />\r\n" +
				"\r\n" +
				"        </s:sequence>\r\n" +
				"      </s:complexType>\r\n" +
				"    </s:schema>\r\n" +
				"  </types>\r\n" +
				"  <message name=\"AddSoapIn\">\r\n" +
				"    <part name=\"parameters\" element=\"s0:Add\" />\r\n" +
				"  </message>\r\n" +
				"  <message name=\"AddSoapOut\">\r\n" +
				"    <part name=\"parameters\" element=\"s0:AddResponse\" />\r\n" +
				"\r\n" +
				"  </message>\r\n" +
				"  <message name=\"TestSoapIn\">\r\n" +
				"    <part name=\"parameters\" element=\"s0:Test\" />\r\n" +
				"  </message>\r\n" +
				"  <message name=\"TestSoapOut\">\r\n" +
				"    <part name=\"parameters\" element=\"s0:TestResponse\" />\r\n" +
				"  </message>\r\n" +
				"  <portType name=\"MathsServiceSoap\">\r\n" +
				"    <operation name=\"Add\">\r\n" +
				"\r\n" +
				"      <input message=\"s0:AddSoapIn\" />\r\n" +
				"      <output message=\"s0:AddSoapOut\" />\r\n" +
				"    </operation>\r\n" +
				"    <operation name=\"Test\">\r\n" +
				"      <input message=\"s0:TestSoapIn\" />\r\n" +
				"      <output message=\"s0:TestSoapOut\" />\r\n" +
				"    </operation>\r\n" +
				"  </portType>\r\n" +
				"  <binding name=\"MathsServiceSoap\" type=\"s0:MathsServiceSoap\">\r\n" +
				"\r\n" +
				"    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"document\" />\r\n" +
				"    <operation name=\"Add\">\r\n" +
				"      <soap:operation soapAction=\"http://tempuri.org/Add\" style=\"document\" />\r\n" +
				"      <input>\r\n" +
				"        <soap:body use=\"literal\" />\r\n" +
				"      </input>\r\n" +
				"      <output>\r\n" +
				"        <soap:body use=\"literal\" />\r\n" +
				"      </output>\r\n" +
				"\r\n" +
				"    </operation>\r\n" +
				"    <operation name=\"Test\">\r\n" +
				"      <soap:operation soapAction=\"http://tempuri.org/Test\" style=\"document\" />\r\n" +
				"      <input>\r\n" +
				"        <soap:body use=\"literal\" />\r\n" +
				"      </input>\r\n" +
				"      <output>\r\n" +
				"        <soap:body use=\"literal\" />\r\n" +
				"      </output>\r\n" +
				"\r\n" +
				"    </operation>\r\n" +
				"  </binding>\r\n" +
				"  <service name=\"MathsService\">\r\n" +
				"    <port name=\"MathsServiceSoap\" binding=\"s0:MathsServiceSoap\">\r\n" +
				"      <soap:address location=\"http://localhost/MathWebService/Maths.asmx\" />\r\n" +
				"    </port>\r\n" +
				"  </service>\r\n" +
				"</definitions>";
		}
	}
}
